﻿using Hydrogen.ULib.Attributes;
using System;
using System.Xml;

namespace Hydrogen.MarkovChain
{
    [RuleNodeName(RuleConstant.NODE_MK), Serializable]
    public class RuleMK :
        RuleNodeBase,
        IRuleNodeExcuteable,
        IRuleNodeSolidReplace
    {
        [UnityEngine.SerializeField, ReadOnly]
        private string _inStr;
        [UnityEngine.SerializeField, ReadOnly]
        private string _outStr;


        public SolidBlockBase In { get; }
        public SolidBlockBase Out { get; }
        /// <summary>
        /// 使用次数，-1为无限次使用.<br/>
        /// 执行成功时 -1
        /// </summary>
        private int _life = -1;
        /// <summary>
        /// 操作方式<br/>
        /// 0 - 一个循环操作一个色块
        /// 1 - 一个循环操作所有符合条件的色块
        /// </summary>
        private int _method = 0;
        private string _testID;
#if HYD_TEST_MODE
#endif

        //public List<SolidType> InSolidType => this._inSolidType;
        //private List<SolidType> _inSolidType;
        //public List<SolidType> OutSolidType => this._outSolidType;
        //private List<SolidType> _outSolidType;

        public RuleMK(XmlNode node) : base(node)
        {
            this._inStr = node.GetAttributeValue(RuleConstant.MK_ATT_IN);
            this._outStr = node.GetAttributeValue(RuleConstant.MK_ATT_OUT);

            if (!string.IsNullOrEmpty(this._inStr))
                //this._inSolidType = Utils.Str2SolidType(this._inStr);
                In = new SolidBlock(this._inStr);
            if (!string.IsNullOrEmpty(this._outStr))
                //this._outSolidType = Utils.Str2SolidType(this._outStr);
                Out = new SolidBlock(this._outStr);

            this._method = node.GetAttributeValueInt(RuleConstant.MK_METHOD, 1);
            this._testID = node.GetAttributeValue("testID");
#if HYD_TEST_MODE

#endif

            Reset();
        }

        public bool TryExcute(Func<IRuleNodeSolidReplace, bool> excuteAcvive)
        {
            if (this._life == 0) return false;
            if (excuteAcvive == null) return false;

            switch (this._method)
            {
                default:
                    if (!excuteAcvive(this)) return false;
                    this._life--;
                    return true;
                case 1:
                    bool success = false;
                    while (this._life != 0 && excuteAcvive(this))
                    {
                        this._life--;
                        success = true;
                    }

                    return success;
            }
        }

        public override void Reset()
        {
            base.Reset();

            if (!int.TryParse(this._node.GetAttributeValue(RuleConstant.MK_LIFE), out this._life))
                this._life = -1;
        }
    }
}
